-- ======================================================================
-- Hell Logic Sniffer Addon 
-- 
-- Copyright 2013 Hell-Prototypes
--
-- http://www.hellprototypes.com/
-- ======================================================================

---[[
ModuleClass = "LS_PLUGIN"
ModuleName  = "Plugin API Description"
ModuleTip   = "Description Plugin API"
--]]
--<*>---------------------------------------------------------------------------
HLS_Pluin_System = [[
================================================================================
=                    Hell Logic Sniffer插件系统接口说明                        =
================================================================================
1.全局名称要求
 1.1 插件文件根据需要包含以下全局的字符串变量：
    (1) ModuleClass : 插件类型，必需定义
        插件类型定义支持："LS_DECODER" 和 "LS_PLUGIN"两种。
        说明： "LS_DECODER"：为协议解码类，用于对通道数据进行解码
               "LS_PLUGIN"：为插件类，用于做一些自定义的扩展数据处理。
               
    (2) ModuleName ：插件名称，必需定义
        当ModuleClass ="LS_DECODER"时，ModuleName表示支持的解码方式,
        系统支持："RS232", "IIC", "SPI", "CUSTOM" 五种定义。

        当ModuleClass ="LS_PLUGIN"时，ModuleName为插件名称，会显示在
        插件列表上。

    (3) ModuleTip ：插件提示，可选定义
		LS_DECODER类：提示会显示在解码设置对话框的下方
        LS_PLUGIN 类：用于当鼠标移到插件列表上时显示当前插件的功能提示说明。

	(4) ModuleAlias：
		当解码插件为CUSTOM插件时，ModuleAlias用与声明解码器的别名，别名会
		显示在解码设置对话框的插件列表中。
	
	(5) ModuleParam1 ~ ModuleParam6：
		当解码插件为CUSTOM插件时，用于声明6个参数输入框左边的提示信息，6个
		参数可按顺序复选，没有声明的项会被禁用。

  1.2.1 解码类声明方式如：
          ModuleClass = "LS_DECODER"
          ModuleName  = "RS232"
          ModuleTip   = "To decode rs232 data"
          "CUSTOM"插件专用：
          ModuleAlias = "CAN Bus"
		  ModuleParam1= "CH Number"
		  ModuleParam2= "Bit Rate"

  1.2.2 插件类声明方式如：
          ModuleClass = "LS_PLUGIN"
          ModuleName  = "Plugin API example"
          ModuleTip   = "Description plugin API and run example"

2.函数定义要求
    插件文件必须包含一个名称为main()的入口函数，系统使用该函数来调用插件。
    如：
        function main()
            LS_API.MessageBox("Hello world!")
        end

3.全局参数
    3.1 当插件类型为"LS_DECODER"时，插件系统会设置一个名字为 LS_PARAM 的全
       局table变量，变量会根据“ModuleName”的解码方式设置不同的内容。
        (1) "RS232":
          LS_PARAM[1] : 需要解码的通道编号：0 ~ 15
          LS_PARAM[2] : 数据位宽：5，6，7，8
          LS_PARAM[3] : 校验模式：NONE：0; ODD:1; EVEN:2; SPACE:3
          LS_PARAM[4] : 停止位个数：0: 1bit, 1: 1.5bit, 2: 2bit
          LS_PARAM[5] : 波特率(>0)
        (2) "IIC"
          LS_PARAM[1] : IIC时钟通道编号
          LS_PARAM[2] : IIC数据通道编号
        (3) "SPI": 
          LS_PARAM[1] : MOSI通道编号
          LS_PARAM[2] : MISO通道编号
          LS_PARAM[3] : SCLK通道编号
          LS_PARAM[4] : SS通道编号
          LS_PARAM[5] : SPI模式: 0 ~ 3
          LS_PARAM[6] : 位顺序：1:MSB, 0:LSB
        (4) "CUSTOM": 
          LS_PARAM[1] : 参数1
          LS_PARAM[2] : 参数2
          LS_PARAM[3] : 参数3
          LS_PARAM[4] : 参数4
          LS_PARAM[5] : 参数5
          LS_PARAM[6] : 参数6
		  注：未使用ModuleParam<1~6>声明的参数项值为-1。

    3.2 当插件类型为"LS_PLUGIN"时，没有此参数。

4.系统开放的API详见：<API说明>
]]
--<*>---------------------------------------------------------------------------
API_Description = [[
================================================================================
=                                 API说明                                      =
================================================================================
]]
--<Message>---------------------------------------------------------------------
MessageBox = [[
格式：LS_API.MessageBox(...)
说明：弹出提示对话框，参数个数不限，参数间用','号隔开。
        参数类型：静态的数字、字符串或变量。
返回值：nil
示例：LS_API.MessageBox("Hello", 1234, "test")
      LS_API.MessageBox(234)
]]
--<Message>---------------------------------------------------------------------
DebugMsg = [[
格式：LS_API.DebugMsg(...)
说明：格式和用法LS_API.MessageBox(...)类似，但消息输出到插件的调试信息区。
返回值：nil
]]
--<Input>-----------------------------------------------------------------------
InputBox = [[
格式：LS_API.InputBox(number or text, note message)
说明：弹出输入对话框，用于输入数字或字符串数据，对话框类型由第一个参数类型决定。
        如果对话框被取消，返回nil。
返回值：数字或字符串, nil
示例：
    num_ret = LS_API.InputBox(234, "input box tip"),
    解释：输出数字, 默认值为 ：234，提示信息为： input box tip

    str_ret = LS_API.InputBox("text", "input text box tip")
    解释：输出字符串，默认值为："text" 提示信息为：input text box tip

    str_ret = LS_API.InputBox()
    解释：输出字符串，无默认值，使用系统默认的提示信息。
]]
--<Input>-----------------------------------------------------------------------
MultiInputBox = [[
格式：LS_API.MultiInputBox(table_param)
说明：弹出多项型输入对话框，用于同时获取多个数字输入，参数：table_param 必须为
      table类型，字符串项作为提示，数字项作为默认值，数字项不足时默认为0，用双
      引号包的纯数字的字符串会作为数字处理。
返回值：数据以table返回，每个table项包含一个数字，顺序与参数相同
        对话框被取消或关闭返回 nil 空值
示例：
    ret_tab = LS_API.MultiInputBox( {"SS", 0, "MOSI", 1, "MISO", 2, "SCK", 3 }),
    解释：显示4个输入框数字, 默认值为 ：0,1,2,3，

    param = {"SS",  "MOSI", "MISO", "SCK", 0, 1, 2, 3 }
    ret_tab = LS_API.MultiInputBox( param),
    解释：与上一个例子效果完全相同
]]
--<Param>-----------------------------------------------------------------------
GetCommonParameter = [[
格式：LS_API.GetCommonParameter()
说明：获取两个光标位置、采样周期值和当前选中的通道。
返回值：参数以table返回。
        table[1] : 采样周期值, 单位是：纳秒(nS)
        table[2] : 左光标(Left)所在位偏移的索引值
        table[3] : 右光标(Right)所在位偏移的索引值
        table[4] : 当前选中的通道：0 ~ 15； 还没有选择当前通道: -1。
示例：common_param = LS_API.GetCommonParameter()
    返回值在common_param[1]； common_param[2]；
              common_param[3]； common_param[4],中。
]]
--<Data>------------------------------------------------------------------------
GetChannelData = [[
格式：LS_API.GetChannelData(channel_number)
说明：获取指定通道的数据，参数：channel_number ：0 ~ 15
返回值：数据以table返回，每个table项包含一个整型数据。
         数据格式说明：通道数据中记录的是该通道电平跳变时的位偏移索引和跳变
                       类型（1:上升沿/0:下降沿），所以一个边沿数据占有用两个table项；
        如果参数错误，或指定通道没有数据，则返回"nil"。
示例：ch_data = LS_API.GetChannelData(2)
         获取第二个通道的数据：
         ch_data[1] -> 第1个数据的位偏移索引
         ch_data[2] -> 第1个数据的跳变类型（1:上升沿/0:下降沿）
         ch_data[3] -> 第2个数据的位偏移索引
         ch_data[4] -> 第2个数据的跳变类型（1:上升沿/0:下降沿）
         ...
         ch_data[#ch_data-1] -> 最后一个数据的位偏移索引
         ch_data[#ch_data]   -> 最后一个数据的跳变类型（1:上升沿/0:下降沿）
]]
--<Report>----------------------------------------------------------------------
ReportPushBack = [[
格式：LS_API.ReportPushBack(message)
说明：当插件类型为"LS_PLUGIN"时，用来向“插件报告对话框”输出消息。
      插件报告对话框只有在此API至少被有效调用一次后才会弹出。
      参数只接受数字或字符串类型。
      *注：此API是插件显示处理结果的主要方式。
返回值：0: 成功；
       -1: 没有参数；
       -2: 参数不是字符串类型或无法转成字符串类型

示例：LS_API.ReportPushBack("Report message")
]]
--<Report>----------------------------------------------------------------------
DecodeElementPushBack = [[
格式：LS_API.DecodeElementPushBack(table)
说明：当插件类型为"LS_DECODER"时, 用来把单个解码单元压到系统的临时缓存内。
       顺序为“先入在前”的方式，插件执行完后自动送给显示组件。

参数：必需为table类型的参数，table的表项至少要有2个，除[2]项外所有项的类型为数字，
       格式如：
        decode_out[1] = 812     ->采样点的起始位置
        decode_out[2] = 23      ->采样数据或字符说明，可以是数字或字符串
        decode_out[3] = 812     ->采样点的第一个位置
        ...
        decode_out[n-1] = 2006  ->采样点的倒数第二个位置
        decode_out[n]   = 2010  ->采样点的最后一个位置
      注：
       * decode_out[1]项的特殊说明：
          在为SPI解码时：decode_out[1]的值小于 0 时为MISO的数据
                          decode_out[1]的值大于等于 0 时为MOSI的数据
       * decode_out[2]项的特殊说明：
          在为RS232解码时：-1: 为校验位错标志, -2: 为停止位错标志
          在为IIC解码时：  -1: 为起始位标志；
                           -2: 为停止位标志；
                           -256~-512：有NAK标志的数据

返回值：0: 成功；
       -1: 参数个数不是一个；
       -2: 参数不是table类型；
       -3: 表项的数目少于2个；
       -4: 表的第一项不是数字；
       -5: 表的第二项不是数字；
       -6: 表的其它项不是数字；

示例：LS_API.DecodeElementPushBack(table)
]]
--<Report>----------------------------------------------------------------------
DecodeElementRemoveLast = [[
格式：LS_API.DecodeElementRemoveLast()
说明：用来移除由LS_API.DecodeElementPushBack(table)压入缓存的最后一项
返回值：nil
]]
--<Operate>---------------------------------------------------------------------
MoveLeftCursorTo = [[
格式：LS_API.MoveLeftCursorTo(bit_index)
说明：移动左光标到bit_index位置。
返回值：0: 成功；
       -1: 参数个数不是一个；
       -2: 参数不是数字类型；
       -3: 参数值超出当前数据位范围；
]]
--<Operate>---------------------------------------------------------------------
MoveRightCursorTo = [[
格式：LS_API.MoveRightCursorTo(bit_index)
说明：移动右光标到bit_index位置。
返回值：0: 成功；
       -1: 参数个数不是一个；
       -2: 参数不是数字类型；
       -3: 参数值超出当前数据位范围；
]]
--<Data>------------------------------------------------------------------------
GetChannelDecodedData = [[
格式：LS_API.GetChannelDecodedData(channel_number)
说明：获取指定通道解码后的数据，参数：channel_number ：0 ~ 15
返回值：数据以table返回，每个table项包含一个整型数据或字符串。
         数据格式说明：通道数据中记录的是该通道解码数据的位偏移和解码后的字符串数
                       据，所以一个解码数据占有用两个table项；
        如果参数错误，或指定通道没有数据，则返回"nil"。
示例：decoded_data = LS_API.GetChannelDecodedData(2)
         获取第二个通道的解码数据：
         decoded_data[1] -> 第1个解码数据的位偏移索引
         decoded_data[2] -> 第1个解码数据的字符串
         decoded_data[3] -> 第2个解码数据的位偏移索引
         decoded_data[4] -> 第2个解码数据的字符串
         ...
         decoded_data[#decoded_data-1] -> 最后一个解码数据的位偏移索引
         decoded_data[#decoded_data]   -> 最后一个解码数据的字符串
    注：Demo文件: e.g.GetDecodeData.lua
]]
--<Data>------------------------------------------------------------------------
GetChannelPosedgeTable = [[
格式：LS_API.GetChannelPosedgeTable(channel_number)
说明：获取指定通道上升沿的位偏移列表，参数：channel_number ：0 ~ 15
返回值：数据以table返回，每个table项包含一个表示上升沿位偏移的整型数据。
        如果参数错误，或指定通道没有数据，则返回"nil"。
示例：posedge_tab = LS_API.GetChannelPosedgeTable(2)
         获取第二个通道的上升沿的位偏移列表：
         posedge_tab[1] -> 第1个上升沿位偏移值
         posedge_tab[2] -> 第2个上升沿位偏移值
         ...
         posedge_tab[#posedge_tab]   -> 最后一个上升沿位偏移值
]]
--<Data>------------------------------------------------------------------------
GetChannelNegedgeTable = [[
格式：LS_API.GetChannelNegedgeTable(channel_number)
说明：获取指定通道下降沿的位偏移列表，参数：channel_number ：0 ~ 15
返回值：数据以table返回，每个table项包含一个表示下降沿位偏移的整型数据。
        如果参数错误，或指定通道没有数据，则返回"nil"。
示例：negedge_tab = LS_API.GetChannelNegedgeTable(2)
         获取第二个通道的下降沿的位偏移列表：
         negedge_tab[1] -> 第1个下降沿位偏移值
         negedge_tab[2] -> 第2个下降沿位偏移值
         ...
         negedge_tab[#posedge_tab]   -> 最后一个下降沿位偏移值
]]
--<Data>------------------------------------------------------------------------
GetChannelLevelByIndex = [[
格式：LS_API.GetChannelLevelByIndex(ch_num, bit_offset)
说明：从指定通道获取指定位偏移的逻辑值，参数：ch_num : 0 ~ 15，bit_offset : >= 0
返回值：1: 逻辑高, 0: 逻辑低
        如果参数错误，或指定通道没有数据，则返回"nil"。
示例：level = LS_API.GetChannelLevelByIndex(2, 12800)
      获取第2通道，12800偏移位置的逻辑值
]]
--<Data>------------------------------------------------------------------------
SaveVariable = [[
格式：LS_API.SaveVariable(key, value)
说明：使用一个索引值保存一个变量，参数：key：索引值，value：要保存的值
      key和value只能是Int型数值或字符串
返回值：nil：失败，true：成功
示例：level = LS_API.SaveVariable("Key", 100)
      以"Key"为索引保存数字100
]]
--<Data>------------------------------------------------------------------------
ReadVariable = [[
格式：LS_API.ReadVariable(key, value)
说明：使用一个索引值读取一个变量，参数：key：索引值
      key和value只能是Int型数值或字符串
返回值：nil：失败，true：成功
示例：level = LS_API.ReadVariable("Key", 100)
      读索引为"Key"的数据
]]
--<Note>------------------------------------------------------------------------
Disabled_STD_Lib = [[
说明：为了安全部份Lua的标准库被禁用，如下：
    IO库:
        flush
        output
        popen
        write
    OS库:
        execute
        exit
        remove
        rename
        setlocale
]]

--------------------------------------------------------------------------------
List = {}
List[#List+1]  = HLS_Pluin_System
List[#List+1]  = API_Description
List[#List+1]  = MessageBox
List[#List+1]  = DebugMsg
List[#List+1]  = InputBox
List[#List+1]  = MultiInputBox
List[#List+1]  = GetCommonParameter
List[#List+1]  = GetChannelData
List[#List+1]  = ReportPushBack
List[#List+1]  = DecodeElementPushBack
List[#List+1]  = DecodeElementRemoveLast
List[#List+1]  = MoveLeftCursorTo
List[#List+1]  = MoveRightCursorTo
List[#List+1]  = GetChannelDecodedData
List[#List+1]  = GetChannelPosedgeTable
List[#List+1]  = GetChannelNegedgeTable
List[#List+1]  = GetChannelLevelByIndex
List[#List+1]  = SaveVariable
List[#List+1]  = ReadVariable
List[#List+1]  = Disabled_STD_Lib

function main()
    Decollator = ""
    for i=1,80 do
        Decollator = Decollator .. "="
    end
    for i=1,#List do
        LS_API.ReportPushBack(List[i])
        if (i < #List) and (i > 2) then
            LS_API.ReportPushBack(Decollator)
        end
    end
end

